package com.atguigu.aiproject.config;

import com.atguigu.aiproject.aitools.AdminTools;
import com.atguigu.aiproject.aitools.AiTools;
import com.atguigu.aiproject.aitools.UserTools;
import io.modelcontextprotocol.client.McpSyncClient;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.vectorstore.QuestionAnswerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.mcp.SyncMcpToolCallbackProvider;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiEmbeddingModel;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import java.util.List;

@Configuration
public class AiConfig {
    private final List<McpSyncClient> mcpSyncClients;// 注入所有McpSyncClient实例
    private final AiTools aiTools;

    public AiConfig(List<McpSyncClient> mcpSyncClients, AiTools aiTools) {
        this.mcpSyncClients = mcpSyncClients;
        this.aiTools = aiTools;
    }

    @Bean   // 向量数据库，调用向量模型进行数据转换。向SimpleVectorStore传递EmbeddingModel
    public VectorStore pdfVectorStore(OpenAiEmbeddingModel embeddingModel) {
        return SimpleVectorStore.builder(embeddingModel).build();// 返回一个向量数据库
    }

    @Bean   // 将数据库所有文章向量化以支持语义搜索
    public VectorStore creationVectorStore(OpenAiEmbeddingModel embeddingModel) {
        return SimpleVectorStore.builder(embeddingModel).build();
    }

    @Bean
    @Scope("prototype")//每个chatClient创建一个Memory
    public ChatMemory chatMemory() {
        return MessageWindowChatMemory.builder()
                .maxMessages(10)
                .build();
    }

    // 默认不支持数据库搜索
    @Bean("chatClient")
    public ChatClient chatClient(OpenAiChatModel openAiChatModel) {

        return ChatClient.builder(openAiChatModel)
                // .defaultAdvisors(new SimpleLoggerAdvisor())  //设置日志切面
                // .defaultTools(dateTimeTools)//设置日期切面，自己写日期类
                // .defaultTools(weatherTools)//设置天气预报切面
                .defaultToolCallbacks(new SyncMcpToolCallbackProvider(mcpSyncClients))//设置mcp服务
                .defaultTools(aiTools)
                .build();
    }

    @Bean("pdfClient")
    public ChatClient pdfClient(OpenAiChatModel openAiChatModel, ChatMemory chatMemory, VectorStore pdfVectorStore, AiTools aiTools) {
        return ChatClient.builder(openAiChatModel)
                .defaultSystem("""
                        你是一位专业的PDF文档解析助手，具备强大的文档理解和信息检索能力。请基于提供的PDF文档内容，准确、全面地回答用户的问题。你需要：
                        1. 仔细分析文档中的关键信息和上下文关系
                        2. 提供准确、详细的答案，并标明信息来源
                        3. 当文档中没有相关信息时，明确告知用户
                        4. 保持专业、客观的语调，避免主观臆断
                        5. 对于复杂问题，提供结构化的回答
                        6. 必要时提供相关的背景知识和补充说明
                        """)
                .defaultAdvisors(
                        MessageChatMemoryAdvisor.builder(chatMemory).build(),//记忆多轮会话
                        QuestionAnswerAdvisor
                                .builder(pdfVectorStore)// 基于向量数据库的问答
                                .searchRequest(SearchRequest.builder()  //处理搜索请求
                                        .topK(3)// 搜索结果数量
                                        .similarityThreshold(0.1f)
                                        .build()
                                )
                                .build()
                )
                .defaultTools(aiTools)
                //追加到prompt中
                .build();
    }

    @Bean("textClient")
    public ChatClient textClient(OpenAiChatModel openAiChatModel, AiTools aiTools) {
        return ChatClient.builder(openAiChatModel)
                .defaultTools(aiTools)
                .build();
    }

    @Bean("creationSearchClient") // 文章搜索，按照用户要求搜索数据库中所有文章内容
    public ChatClient creationSearchClient(OpenAiChatModel openAiChatModel, VectorStore creationVectorStore, AiTools aiTools, UserTools userTools) {
        return ChatClient.builder(openAiChatModel)
                .defaultSystem("""
                        你是一个文章查询助手，基于提供的文章数据库，回答用户问题。
                        """)
                .defaultAdvisors(
                        // dicksuck:
                        // 在creationSearchClient中，我们原来使用了QuestionAnswerAdvisor，它会在每次对话时自动进行向量搜索，并返回3个文档作为上下文。
                        // 现在，我们希望AI自己调用vectorStoreQuery工具，所以应该移除这个Advisor，否则会干扰AI的决策。
                        QuestionAnswerAdvisor
                                .builder(creationVectorStore) // 基于数据库中所有文章内容的搜索与问答
                                .searchRequest(
                                        SearchRequest.builder()  // 处理搜索请求
                                                .topK(3) // 搜索结果数量，待定
                                                .similarityThreshold(0.45f)
                                                .build()
                                )
                                .build()
                )
                .defaultTools(aiTools, userTools)
                .build();
    }

    @Bean("aiAdmin")
    public ChatClient aiAdmin(OpenAiChatModel openAiChatModel,
                              ChatMemory chatMemory,
                              VectorStore creationVectorStore,
                              AdminTools adminTools,
                              AiTools aiTools,
                              UserTools userTools
    ) {
        return ChatClient.builder(openAiChatModel)
                .defaultToolCallbacks(new SyncMcpToolCallbackProvider(mcpSyncClients))// 设置mcp服务
                .defaultTools(adminTools, aiTools, userTools) // ai管理员的sql执行器，允许删库跑路
                .defaultAdvisors(
                        MessageChatMemoryAdvisor.builder(chatMemory).build(), // 记忆多轮会话
                        QuestionAnswerAdvisor
                                .builder(creationVectorStore) // 基于数据库中所有文章内容的搜索与问答
                                .searchRequest(
                                        SearchRequest.builder()  //处理搜索请求
                                                .topK(3) // 搜索结果数量，待定
                                                .similarityThreshold(0.1f)
                                                .build()
                                )
                                .build())
                .build();
    }
    @Bean("contentReviewClient")
    public ChatClient contentReviewClient(OpenAiChatModel openAiChatModel) {
        return ChatClient.builder(openAiChatModel)
                .defaultSystem("""
                    你是一个专业的内容审核员，负责审核用户创作的内容是否合法合规。
                    你需要根据中国法律法规和社会主义核心价值观来判断内容的合规性。
                    """)
                .build();
    }
}

